<template>
  <div :class="['components-chart-box', chartClass, props.bordered && 'bordered', props.theme]">
    <h4 v-if="props.title" class="chart-title" ref="titleRef">{{ props.title }}</h4>
    <a-button @click="toggleChartType" style="position: absolute;
    top: 30px;
    left: 15px;
    z-index: 999;
    ">{{ chartType === 'line' ? '切换到柱状图' : '切换到曲线图' }}</a-button>
    <a-select :getPopupContainer="(triggerNode) => { return triggerNode.parentNode || document.body }"
      v-if="isFirstInitial" :maxTagCount="1" mode="multiple" :class="['chart-title-right', 'min-w-48']"
      :options="selectOptions" :disabled="selectOptions.length < 2" :value="selectLegendValue" @select="handleSelect"
      @deselect="handleDeSelect" @change="handleChange" allowClear>
    </a-select>
    <!-- 添加切换按钮 -->

    <div :class="['chart-container']" v-loading="loading" ref="chartRef" :style="{ height, width, marginTop: '10px' }">
    </div>
  </div>
</template>

<script lang="ts" setup>
import { onMounted, PropType, Ref, ref, watch, onUnmounted } from 'vue'

import { useECharts } from '@/hooks/web/useECharts'
import { EChartsOption } from 'echarts'
import { getCssVariableValue, getRandomColor, lightenColor } from '@/components/Charts/common'
import { lineColorArr } from '@/components/Charts/Line/data'
import '@/components/Charts/style.scss'
import { XAXisOption } from 'echarts/types/dist/shared'

const props = defineProps({
  width: {
    type: String as PropType<string>,
    default: '100%',
  },
  height: {
    type: String as PropType<string>,
    default: '100%',
  },
  loading: {
    type: Boolean,
    default: false,
  },
  bordered: {
    type: Boolean,
    default: true,
  },
  title: {
    type: String as PropType<string>,
    default: '',
  },
  chartData: {
    type: Object as PropType<object>,
  },
  chartClass: {
    type: Object as PropType<string>,
  },
  unit: {
    type: String as PropType<string>,
    default: '',
  },
  xyDataFieldsName: {
    type: Object as PropType<{
      xDataField: string
      yDataField: string
    }>,
    default: () => ({
      xDataField: 'xaxisList',
      yDataField: 'yaxisList',
    }),
  },
  theme: {
    type: String,
    default: 'white'
  },
})

let resizeObserver: ResizeObserver | null = null
// 初始化时关闭图例选择框
const isFirstInitial = ref(false)
const selectOptions = ref([])
const selectLegendValue = ref([])
const chartRef = ref<HTMLDivElement | null>(null)
const titleRef = ref<HTMLDivElement | null>(null)
const { setOptions, echarts, resize, getInstance } = useECharts(chartRef as Ref<HTMLDivElement>)
const gridLineColor = props.theme === 'dark' ? 'rgba(255,255,255,0.12)' : getCssVariableValue('--chart-grid-line-color')
const textColor = props.theme === 'dark' ? 'rgba(255,255,255,0.70)' : getCssVariableValue('--chart-text-color')

// 标题高度 + 上间距 + 标题距离 grid 间距
const gridTop = 18 + 12 + 12 + 25
const options: EChartsOption = {
  legend: {
    show: false,
    right: 16,
    padding: 0,
    top: 15,
    textStyle: {
      color: textColor,
    },
    icon: 'rect',
    itemWidth: 11,
    itemHeight: 2,
  },
  grid: {
    left: '35px',
    right: '0px',
    bottom: '12px',
    top: gridTop,
    containLabel: true,
  },
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      type: 'cross',
      snap: true,
      label: {
        show: true,
        backgroundColor: '#333',
      },
    },
    confine: true,
    appendToBody: true,
    className: ['echarts-line-tooltip', props.theme].join(' '),
    backgroundColor: props.theme === 'dark' ? 'rgba(50,68,121,0.50);' : '#fff',
    // 优化 formatter 函数，显示所有系列数据
    formatter: function (params) {
      if (!params || params.length === 0) return '';

      // 格式化标题（x轴值）
      const title = params[0].name || '';

      // 生成系列数据内容
      const seriesContent = params.map(param => {
        return `${param.seriesName}: ${param.value}`;
      }).join('<br/>');

      return `<div class="echarts-tooltip-title">${title}</div>${seriesContent}`;
    }
  },
  xAxis: {
    axisLine: {
      lineStyle: {
        color: gridLineColor,
      },
    },
    axisLabel: {
      color: textColor,
    },
  },
  yAxis: {
    nameTextStyle: {
      color: textColor,
      fontSize: '12px',
    },
    splitLine: {
      lineStyle: {
        color: gridLineColor,
      },
    },
    axisLine: {
      lineStyle: {
        color: gridLineColor,
      },
    },
    axisLabel: {
      color: textColor,
    },
  },
}

// 新增图表类型状态
const chartType = ref('line')

onMounted(() => {
  setData()

  resizeObserver = new ResizeObserver(() => {
    resize()
  })
  if (chartRef.value) {
    resizeObserver.observe(chartRef.value as HTMLDivElement)
  }
})

onUnmounted(() => {
  if (resizeObserver && chartRef.value) {
    resizeObserver.unobserve(chartRef.value as HTMLDivElement)
  }
})

// 只负责图例的选中项
const handleChange = (params: any) => {
  selectLegendValue.value = params
  const originOption = getInstance()?.getOption() as EChartsOption

  if (originOption?.legend) {
    Object.keys(originOption.legend[0].selected).forEach(key => {
      if (selectLegendValue.value.includes(key)) {
        originOption.legend[0].selected[key] = true
      } else {
        originOption.legend[0].selected[key] = false
      }
    })
    setOptions(originOption)
  }
}

const setData = () => {
  const { xDataField, yDataField } = props.xyDataFieldsName
  if (!props.chartData || !chartRef.value) return
  const chartTitleW = titleRef.value ? titleRef.value.offsetWidth : 0
  const legendWidth = chartRef.value?.clientWidth - chartTitleW - 36
  const xData = props.chartData[xDataField]
  const yData = props.chartData[yDataField]
  if (!xData || !yData) return
  selectOptions.value = yData.map((item) => ({
    label: item?.name || '',
    value: item?.name || '',
  }))

  // 修改成默认选中第一个图例
  selectLegendValue.value = yData[0]?.name || ''

  const showUnit = yData.length && props.unit
  setOptions({
    ...options,
    legend: {
      ...options.legend,
      width: legendWidth,
      data: yData.map((item) => item?.name || ''),
      selected: yData.reduce((prev, item, index) => {
        index == 0 ? (prev[item?.name || ''] = true) : (prev[item?.name || ''] = false)
        return prev
      }, {}),
      type: 'scroll',
      pageTextStyle: {
        color: textColor
      }
    },
    grid: {
      ...options.grid,
      top: showUnit ? gridTop + 14 : gridTop,
    },
    xAxis: {
      ...options.xAxis,
      data: xData,
    } as XAXisOption,
    yAxis: {
      ...options.yAxis,
      name: showUnit && `单位：${props.unit}`,
    },
    series: yData.map((item, index) => {
      let colorArr = lineColorArr?.[index]

      if (!colorArr) {
        const color1 = getRandomColor()
        const color2 = lightenColor(color1)
        colorArr = [color1, color2]
      }

      return {
        ...item,
        type: chartType.value, // 根据 chartType 动态设置图表类型
        smooth: chartType.value === 'line', // 曲线图设置平滑

        // 隐藏默认标记点
        showSymbol: false,

        // 鼠标悬停时的强调效果
        emphasis: {
          focus: 'series',
        },

        itemStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
            { offset: 0, color: colorArr[0] },
            { offset: 1, color: colorArr[1] },
          ]),
        },
        lineStyle: {
          width: 2, // 增加线条宽度，便于鼠标捕捉
        },
      }
    }),
  })

}

// 切换图表类型的方法
const toggleChartType = () => {
  chartType.value = chartType.value === 'line' ? 'bar' : 'line'
  setData()
}

watch(
  () => props.chartData,
  (val) => {
    setData()
  },
  {
    immediate: true,
  },
)

watch(selectOptions, () => {
  selectOptions.value.length && (isFirstInitial.value = true)
})

defineExpose({})

</script>

<style lang="scss" scoped>
.echarts-line-tooltip {
  &.dark {
    border-color: rgb(162 193 255 / 30%) !important;

    .legend-list {
      li {
        color: #fff;
      }
    }
  }

  .legend-list {
    li {
      display: flex;
      align-items: center;
      color: #666;
      font-size: 12px;
      line-height: 24px;

      &:not(:last-child) {
        margin-bottom: 4px;
      }

      .rect {
        display: block;
        width: 11px;
        height: 2px;
        margin-right: 3px;
      }
    }
  }

}
</style>